﻿using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;

namespace Tests
{
    public class Node : IComparable
    {
        public float Weight = 10;
        public Node Parent = null;
        public bool IsObstacle = false;

        public Node[] Neighbours = new Node[4];

        public MeshRenderer Render;

        private Color m_color;
        public Color Color
        {
            get => m_color;
            set
            {
                m_color = value;
            }
        }

        public float TotalCost
        {
            get => totalCost;
            set
            {
                totalCost = value;
                string v = value.ToString();
                if (v == "0")
                {
                    v = "";
                }

            }
        }

        private float totalCost = 0;


        public Node(int w = 0)
        {
            this.Weight = w;
        }

        public Node[] GetNeighbour()
        {

            return Neighbours;
        }

        public void SetAsObstacle()
        {
            Color = Color.red;
            IsObstacle = true;
           
        }

        public void SetAsPassable()
        {
            Color = Color.white;
            IsObstacle = false;
        }

        public void SetAsStart()
        {
            Color = Color.green;
            //transform.position += Vector3.up;
        }

        public void SetAsGoal()
        {
            Color = Color.yellow;
            //transform.position += Vector3.up;
        }


        public int CompareTo(object obj)
        {
            Node a = obj as Node;

            return this.Weight.CompareTo(a.Weight);
        }

        public void SetColor(Color color)
        {
            Color = color;
        }
    }
    public class PriorityQueue
    {
        List<Node> nodes = new List<Node>();

        private int count;

        public int Count { get => nodes.Count; set => count = value; }

        public void Add(Node node)
        {
            node.SetColor(Color.blue);
            // 这里的sort没有判断node权重值相等的情况，可能排序后取得的值是乱的，所以单独做下处理
            if (nodes.Count > 0 && node.Weight <= nodes[0].Weight)
            {
                nodes.Insert(0, node);
            }
            else
            {
                nodes.Add(node);
                nodes.Sort();
            }
        }

        public void Remove(Node node)
        {
            node.SetColor(Color.red);
            nodes.Remove(node);
            nodes.Sort();
        }

        public Node GetFirst()
        {
            nodes[0].SetColor(Color.yellow);
            return nodes[0];
        }

        public bool Contains(Node node)
        {
            return nodes.Contains(node);
        }

        public void Clear()
        {
            nodes.Clear();
        }
    }


    public class NewTestScript
    {
        // A Test behaves as an ordinary method
        [Test]
        public void NewTestScriptSimplePasses()
        {
            PriorityQueue priorityQueue = new PriorityQueue();
            priorityQueue.Add(new Node(20));
            Node node = new Node(12);
            node.TotalCost = 2f;
            Node node2 = new Node(12);
            node2.TotalCost = 3f;
            priorityQueue.Add(node);
            priorityQueue.Add(new Node(12));
            priorityQueue.Add(new Node(12));
            priorityQueue.Add(new Node(12));
            priorityQueue.Add(node2);
            priorityQueue.Add(new Node(99));

            Debug.Log(priorityQueue.GetFirst().Weight + " " + priorityQueue.GetFirst().TotalCost.ToString());
        }

        // A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use
        // `yield return null;` to skip a frame.
        [UnityTest]
        public IEnumerator NewTestScriptWithEnumeratorPasses()
        {
            // Use the Assert class to test conditions.
            // Use yield to skip a frame.
            yield return null;
        }
    }
}
